#include "Common/ScannerInterface.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>

#ifdef _WIN32
    #include <windows.h>
#else
    #include <dlfcn.h>
#endif

// 全局变量用于测试
std::atomic<int> fileCount(0);
std::atomic<uint64_t> totalSize(0);
std::atomic<bool> scanCompleted(false);

// 进度回调函数
void progressCallback(const wchar_t* filePath, uint64_t fileSize, uint64_t totalFiles) {
    fileCount++;
    totalSize += fileSize;
    
    // 每100个文件输出一次进度
    if (fileCount % 100 == 0) {
        std::wcout << L"已扫描 " << fileCount << L" 个文件，当前: " 
                   << filePath << L" (" << fileSize << L" bytes)" << std::endl;
    }
}

// 完成回调函数
void completeCallback(const ScanResult* results, int count, int status) {
    std::cout << "\n扫描完成!" << std::endl;
    std::cout << "状态: " << status << std::endl;
    std::cout << "总文件数: " << count << std::endl;
    std::cout << "回调统计 - 文件数: " << fileCount.load() 
              << ", 总大小: " << totalSize.load() << " bytes" << std::endl;
    
    // 显示前10个文件
    std::cout << "\n前10个文件:" << std::endl;
    for (int i = 0; i < std::min(count, 10); ++i) {
        std::wcout << L"  " << results[i].filePath 
                   << L" (" << results[i].fileSize << L" bytes)" << std::endl;
    }
    
    scanCompleted = true;
}

int main(int argc, char* argv[]) {
    std::cout << "=== 文件扫描器DLL测试程序 ===" << std::endl;
    
    // 获取扫描路径
    std::string scanPath = "/home/lyt";  // 默认路径
    if (argc > 1) {
        scanPath = argv[1];
    }
    
    std::cout << "扫描路径: " << scanPath << std::endl;
    
#ifdef _WIN32
    // Windows DLL加载
    HMODULE dll = LoadLibraryA("FileScanner.dll");
    if (!dll) {
        std::cerr << "无法加载 FileScanner.dll" << std::endl;
        return 1;
    }
    
    auto CreateScanner = (HANDLE(*)())GetProcAddress(dll, "CreateScanner");
    auto DestroyScanner = (void(*)(HANDLE))GetProcAddress(dll, "DestroyScanner");
    auto StartScan = (bool(*)(HANDLE, const wchar_t*))GetProcAddress(dll, "StartScan");
    auto StopScan = (void(*)(HANDLE))GetProcAddress(dll, "StopScan");
    auto IsScanning = (bool(*)(HANDLE))GetProcAddress(dll, "IsScanning");
    auto SetProgressCallback = (void(*)(HANDLE, ProgressCallbackC))GetProcAddress(dll, "SetProgressCallback");
    auto SetCompleteCallback = (void(*)(HANDLE, CompleteCallbackC))GetProcAddress(dll, "SetCompleteCallback");
    auto GetTotalFilesScanned = (uint64_t(*)(HANDLE))GetProcAddress(dll, "GetTotalFilesScanned");
    auto GetTotalBytesScanned = (uint64_t(*)(HANDLE))GetProcAddress(dll, "GetTotalBytesScanned");
#else
    // Linux SO加载
    void* dll = dlopen("./libFileScanner.so", RTLD_LAZY);
    if (!dll) {
        std::cerr << "无法加载 libFileScanner.so: " << dlerror() << std::endl;
        return 1;
    }
    
    auto CreateScanner = (HANDLE(*)())dlsym(dll, "CreateScanner");
    auto DestroyScanner = (void(*)(HANDLE))dlsym(dll, "DestroyScanner");
    auto StartScan = (bool(*)(HANDLE, const wchar_t*))dlsym(dll, "StartScan");
    auto StopScan = (void(*)(HANDLE))dlsym(dll, "StopScan");
    auto IsScanning = (bool(*)(HANDLE))dlsym(dll, "IsScanning");
    auto SetProgressCallback = (void(*)(HANDLE, ProgressCallbackC))dlsym(dll, "SetProgressCallback");
    auto SetCompleteCallback = (void(*)(HANDLE, CompleteCallbackC))dlsym(dll, "SetCompleteCallback");
    auto GetTotalFilesScanned = (uint64_t(*)(HANDLE))dlsym(dll, "GetTotalFilesScanned");
    auto GetTotalBytesScanned = (uint64_t(*)(HANDLE))dlsym(dll, "GetTotalBytesScanned");
#endif
    
    if (!CreateScanner || !DestroyScanner || !StartScan || !StopScan || 
        !IsScanning || !SetProgressCallback || !SetCompleteCallback ||
        !GetTotalFilesScanned || !GetTotalBytesScanned) {
        std::cerr << "无法获取DLL函数" << std::endl;
        return 1;
    }
    
    std::cout << "DLL加载成功" << std::endl;
    
    // 创建扫描器
    HANDLE scanner = CreateScanner();
    if (!scanner) {
        std::cerr << "创建扫描器失败" << std::endl;
        return 1;
    }
    
    std::cout << "扫描器创建成功" << std::endl;
    
    // 设置回调函数
    SetProgressCallback(scanner, progressCallback);
    SetCompleteCallback(scanner, completeCallback);
    
    // 转换路径为�string
    std::wstring wscanPath(scanPath.begin(), scanPath.end());
    
    // 开始扫描
    std::cout << "开始扫描..." << std::endl;
    if (!StartScan(scanner, wscanPath.c_str())) {
        std::cerr << "启动扫描失败" << std::endl;
        DestroyScanner(scanner);
        return 1;
    }
    
    // 监控扫描进度
    auto startTime = std::chrono::steady_clock::now();
    while (IsScanning(scanner) && !scanCompleted) {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        
        uint64_t files = GetTotalFilesScanned(scanner);
        uint64_t bytes = GetTotalBytesScanned(scanner);
        
        auto currentTime = std::chrono::steady_clock::now();
        auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(currentTime - startTime).count();
        
        std::cout << "进度: " << files << " 文件, " 
                  << (bytes / 1024 / 1024) << " MB, "
                  << elapsed << " 秒" << std::endl;
        
        // 测试中断功能（扫描10秒后停止）
        if (elapsed > 10) {
            std::cout << "测试中断功能..." << std::endl;
            StopScan(scanner);
            break;
        }
    }
    
    // 等待扫描完成
    while (!scanCompleted && IsScanning(scanner)) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    
    // 最终统计
    uint64_t finalFiles = GetTotalFilesScanned(scanner);
    uint64_t finalBytes = GetTotalBytesScanned(scanner);
    
    std::cout << "\n=== 最终统计 ===" << std::endl;
    std::cout << "扫描文件数: " << finalFiles << std::endl;
    std::cout << "总大小: " << (finalBytes / 1024 / 1024) << " MB" << std::endl;
    
    // 清理资源
    DestroyScanner(scanner);
    
#ifdef _WIN32
    FreeLibrary(dll);
#else
    dlclose(dll);
#endif
    
    std::cout << "测试完成" << std::endl;
    return 0;
}